package com.its.us.netty.server.handler;

import com.its.us.netty.server.data.User;
import com.its.us.web.utils.JsonUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.time.LocalTime;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 指定聊天
 *
 * @Author: master
 * @Date: 2020/11/1 19:45
 * @Version: 1.0
 */
public class WebOneSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    // 全局单例实例化唯一
    public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    // 用户id和channel绑定
    private static Map<String, Channel> userChannel = new ConcurrentHashMap<>();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        /*Map<String,Object> map = JsonUtil.fromJson(msg.text());
        if(null!=map.get("type") && "single".equals(map.get("type"))){
            userChannel.put(map.get("id").toString(),ctx.channel());
        }*/
        System.err.println(msg.text());
        // 绑定
        User user = JsonUtil.fromJson(msg.text(), User.class);
        if (null != user.getType() && "single".equals(user.getType())) {
            if (!userChannel.containsKey(user.getId())) {
                userChannel.put(user.getId(), ctx.channel());
            }
        }
        // 处理业务
        if (user.getType() == null && null != user.getSendTo()) {
            userChannel.forEach((s, ch) -> {
                if (user.getSendTo().equals(s)) {
                    ch.writeAndFlush(new TextWebSocketFrame("客户[" + user.getId() + "]发送内容：\n" + user.getMsg() + "\n时间：" + LocalTime.now()));
                }
                if (user.getId().equals(s)) {
                    ch.writeAndFlush(new TextWebSocketFrame("自己[" + user.getId() + "]发送内容：\n" + user.getMsg() + "\n时间：" + LocalTime.now()));
                }
            });
        }

    }

    /**
     * 当web客户端连接后就会触发该方法
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // id 表示唯一的值，LongText 是唯一的
        //System.err.println("handlerAdded 被调用了" + ctx.channel().id().asLongText());
        // 不是唯一的，有可能重复
        //System.err.println("handlerAdded 被调用了" + ctx.channel().id().asShortText());
        ctx.channel().writeAndFlush("[服务：]" + ctx.channel().remoteAddress() + "channel_id" + ctx.channel().id() + " 加入了 \n");
        // 添加到通道组
        channelGroup.add(ctx.channel());
        System.err.println("channelGroup 人数：" + channelGroup.size());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.err.println("handlerRemoved 被调用了" + ctx.channel().id().asLongText());
        // 一旦触发此事件，会自动将 channelGroup 中的channel remove 掉
        channelGroup.writeAndFlush("客户端：【" + ctx.channel().remoteAddress() + "】离开了！时间：" + LocalTime.now());
        Collection<Channel> col = userChannel.values();
        while (true == col.contains(ctx.channel())) {
            col.remove(ctx.channel());
            System.err.println("netty 客户端移除成功");
        }
        System.err.println("userChannel 人数：" + userChannel.size());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.err.println("异常发生：" + cause.getMessage());
        ctx.close();
    }
}
